package com.iwhalecloud.bss.kite.cucc.web.controller.scene;

import java.util.*;
import java.util.stream.Collectors;

import com.iwhalecloud.bss.kite.common.log.KiteLogEnum;
import com.iwhalecloud.bss.kite.common.log.KiteLogger;
import com.iwhalecloud.bss.kite.common.rule.check.ICheckService;
import com.iwhalecloud.bss.kite.common.util.*;
import com.iwhalecloud.bss.kite.cucc.client.api.reception.ICustReceptionService;
import com.iwhalecloud.bss.kite.cucc.client.dto.cust.CuccContextCustDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.scene.CuccCustInfoDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.scene.CuccCustInfoDetailDTO;
import com.iwhalecloud.bss.kite.cucc.service.cache.CuccContextCustCache;
import com.iwhalecloud.bss.kite.cucc.web.service.bigdata.util.OppoToSceneUtils;
import com.iwhalecloud.bss.kite.web.util.RuleParamUtils;
import com.ztesoft.bss.rul.core.client.dto.common.RuleCommonParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.iwhalecloud.bss.kite.cart.client.api.cart.query.IQueryKiteShoppingCartService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.accept.in.AcceptRequestInDTO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProductModuleVO;
import com.iwhalecloud.bss.kite.client.vo.scene.SceneVO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.cucc.client.api.flow.IFlowService;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IReceiptService;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.OneStopTrackInfoVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.OssTrackInfoVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.ReceiptInfoVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.SceneNewOfferSeneVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.TrackInfoVO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.CuccOfferOriginalInfoCache;
import com.iwhalecloud.bss.kite.cucc.service.even.GroupProdAttrEvent;
import com.iwhalecloud.bss.kite.cucc.service.even.KiteCartStatusModifyEvent;
import com.iwhalecloud.bss.kite.cucc.web.service.accept.service.CuccKitePageNavigationCache;
import com.iwhalecloud.bss.kite.cucc.web.service.scene.PageNavigationService;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferAttrCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.dataservice.entity.OfferAttr;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.util.GeneralSwitchUtils;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.transaction.KiteTransactional;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.iwhalecloud.bss.kite.web.service.accept.service.KitePageNavigationCache;
import com.iwhalecloud.bss.kite.web.service.accept.service.SceneVOCache;
import com.iwhalecloud.bss.kite.web.service.accept.vo.PageNavigationVO;
import com.iwhalecloud.bss.kite.web.service.scene.ISceneService;
import com.ztesoft.bss.common.bo.LoginInfo;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.bss.common.util.StringUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * <Description> 大数据场景受理 <br>
 *
 * @author kangchuang <br>
 * @version 1.0<br>
 * @see com.iwhalecloud.bss.kite.web.controller.order <br>
 * @since R9.0<br>
 */
@RestController("bigData")
@RequestMapping("/newForBigData/cuccScene")
@Api(tags = {"/cuccScene - 场景受理，返回页面展示对象,兼容新增和购物车修改过来，从购物车过来只有sceneInstId、templateId、serviceOfferId"
}, description = "初始化在SceneInitController")
public class BigDataSceneController {

    @Autowired
    private ISceneService sceneService;

    @Autowired
    private IQuerySceneService querySceneService;

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private PageNavigationService pageNavigationService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private IFlowService queryFlowService;

    @Autowired
    private IReceiptService queryReceiptService;

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private ICustReceptionService custReceptionService;

    @Autowired
    private ICheckService checkService;
    @KiteTransactional
    @ApiOperation(value = "生成新增套餐场景对象", notes = "生成新增套餐场景对象")
    @ApiImplicitParams({@ApiImplicitParam(name = "offerId", value = "销售品标识"),
        @ApiImplicitParam(name = "templateId", value = "场景模板标识", required = true),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true),
        @ApiImplicitParam(name = "oppoNum", value = "商机编码", required = false)
    })
    @GetMapping
    public DataResult<SceneVO> createNewOfferSceneInst(@RequestParam(required = false) String offerId,
                                                       @RequestParam String sceneInstId, @RequestParam String templateId,@RequestParam(required = false) String cartId, @RequestParam(required = false) String custId, @RequestParam(required = false) String oppoNum) {
        //  KiteSceneInst sceneInst = getSceneInst(sceneInstId);
        LoginInfo loginInfo = ContextUtil.getLoginInfo();
        Map<String, Object> extParams = loginInfo.getUserInfo().getExtParams();
        if (KiteMapUtils.isNotEmpty(extParams) && !KiteStringUtils.isEmpty(cartId)) {
            extParams.put("KITE_SCENEINST_CARTID", cartId);
            ContextUtil.setLoginInfo(loginInfo);
        }
        if (KiteStringUtils.isEmpty(custId)) {
            custId = KiteWebContext.getContext().getCustId();
        }
        /*点击用户规则埋点-start*/
        RuleCommonParam ruleCommonParam = RuleParamUtils.getRuleParam(custId);
        checkService.checkSelectCustData(custId, ruleCommonParam);
        /*点击用户规则埋点-end*/
        this.operateSceneInstService.putExtParameter(sceneInstId, "oppoNum", oppoNum);
        KiteSceneInst sceneInst = this.querySceneInstService
            .getSceneInst(sceneInstId, custId);

        String serviceOfferId = sceneInst.getServiceOfferId();
        if (InstType.PROD_INST.equals(sceneInst.getRootInstType())) {
            //基础销售品
            offerId = ProductCache.get(getSpecId(sceneInst)).getBaseOfferId();
        }
        else {
            offerId = getSpecId(sceneInst);
        }
        //initProdDetail(sceneInstId,offerId);
        AcceptRequestInDTO acceptRequest = new AcceptRequestInDTO();
        acceptRequest.setSceneInstId(sceneInstId).setSceneTemplateId(templateId).setOfferId(offerId)
            .setServiceOfferId(serviceOfferId);
        DataResult<SceneVO> sceneVoResult = sceneService.callEngine(acceptRequest);
        //发布属性分组处理事件
        SceneNewOfferSeneVO sceneVO = (SceneNewOfferSeneVO) sceneVoResult.getResultObject();
        List<ProductModuleVO> productModuleVOList = sceneVO.getSceneProductModuleVO().getProduct();
        Collections.reverse(productModuleVOList);
        GroupProdAttrEvent groupProdAttrEvent = new GroupProdAttrEvent(this, custId,"");
        groupProdAttrEvent.setSceneInstId(sceneInstId);
        groupProdAttrEvent.setProductModuleVOList(productModuleVOList);
        applicationContext.publishEvent(groupProdAttrEvent);
        //发布状态修改事件-场景数据来源为订单中心的不需要保存购物车，不需要修改购物车状态
        String askSource = this.querySceneInstService.getSceneInst(sceneInstId).getAskSource();
//        if (!KiteStringUtils.equals(LocalKeyConsts.ASK_SOURCE_ORDER, askSource)) {
//            KiteCartStatusModifyEvent kiteCartStatusModifyEvent = new KiteCartStatusModifyEvent(this,
//                KiteWebContext.getContext().getCustId(),
//                ContextUtil.getUserId().toString(),
//                ContextUtil.getLoginInfo().getUserInfo().getUserName(),
//                cartId, KeyConsts.SHOPPING_CART_GROUP_STATUS_INPUT, Collections.singletonList(sceneInstId));
//            applicationContext.publishEvent(kiteCartStatusModifyEvent);
//        }
        String saveCartFlag = querySceneInstService.getExtParameterValue(sceneInstId, "saveCart");
        if (!KiteStringUtils.equals(LocalKeyConsts.ASK_SOURCE_ORDER, askSource) && KiteStringUtils.isEmpty(saveCartFlag)) {
            this.operateSceneInstService.putExtParameter(sceneInstId, "saveCart", "saveCart");

            com.iwhalecloud.bss.kite.cucc.web.service.ISceneService cuccSceneService = SpringUtil.getBean(com.iwhalecloud.bss.kite.cucc.web.service.ISceneService.class);
            cuccSceneService.cacheShoppingCartGroup(sceneInstId, sceneInst.getCartId());
        }
        return sceneVoResult;
    }

    @ApiOperation(value = "获取页面导航对象", notes = "获取页面导航对象")
    @ApiImplicitParams({@ApiImplicitParam(name = "serviceOfferId", value = "服务提供标识", required = true),
        @ApiImplicitParam(name = "offerType", value = "销售品类型", required = true),
        @ApiImplicitParam(name = "offerId", value = "销售品标识", required = false),
        @ApiImplicitParam(name = "singleGoodsSku", value = "sku", required = false),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例id", required = false),
        @ApiImplicitParam(name = "custId", value = "客户id", required = false),
        @ApiImplicitParam(name = "oppoNum", value = "商机编码", required = false),
        @ApiImplicitParam(name = "oppoName", value = "商机名称", required = false)
    })
    @GetMapping(value = "/navigation")
    @KiteLogger(isWrite = true, type = KiteLogEnum.CONTROLLER)
    public DataResult<PageNavigationVO> getPageNavigation(@RequestParam String serviceOfferId,
                                                          @RequestParam(required = false) String offerType, @RequestParam(required = false) String offerId,@RequestParam(required = false) String singleGoodsSku,  @RequestParam(required = false) String sceneInstId,@RequestParam(required = false) String custId,@RequestParam(required = false) String oppoNum,@RequestParam(required = false) String oppoName) {

        //根據custId查客戶信息
        CuccCustInfoDetailDTO cuccCustInfoDetailDTO = custReceptionService.getCustomerInfoNew(custId);

        CuccCustInfoDTO cuccCustInfoDTO = new CuccCustInfoDTO();
        cuccCustInfoDTO.setAddress(cuccCustInfoDetailDTO.getAddress());
        cuccCustInfoDTO.setEparchyName(cuccCustInfoDetailDTO.getEparchyName());
        cuccCustInfoDTO.setCustName(cuccCustInfoDetailDTO.getCustName());
        cuccCustInfoDTO.setCustState("0");
        cuccCustInfoDTO.setCustType(cuccCustInfoDetailDTO.getCustClassType());
        cuccCustInfoDTO.setEparchyProvince(cuccCustInfoDetailDTO.getProvinceCode());
        cuccCustInfoDTO.setAddr(cuccCustInfoDetailDTO.getAddress());
        cuccCustInfoDTO.setBbssCustId(cuccCustInfoDetailDTO.getBbssCustId());
        cuccCustInfoDTO.setCustId(cuccCustInfoDetailDTO.getCustId());
        cuccCustInfoDTO.setContactName(cuccCustInfoDetailDTO.getContactName());
        cuccCustInfoDTO.setGroupId(cuccCustInfoDetailDTO.getGroupId());
        cuccCustInfoDTO.setEparchyCity(cuccCustInfoDetailDTO.getEparchyCode());
        cuccCustInfoDTO.setEparchyArea(cuccCustInfoDetailDTO.getBcityCode());
        //商机
        cuccCustInfoDetailDTO.setOppoNum(oppoNum);
        cuccCustInfoDetailDTO.setOppoName(oppoName);
        //初始化客户信息
        this.initContext(cuccCustInfoDetailDTO);
        if(!cuccCustInfoDetailDTO.getEparchyCode().equals(ContextUtil.getLoginInfo().getUserInfo().getPostLanId())){
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("商机转定仅允许对当前工号归属地市的客户进行转定！");
        }
        String oldServiceOfferId = serviceOfferId;
        if (GeneralSwitchUtils.isSwitchOpened("CUCC_KITE_PAGE_NAVIGATION")) {
            // 取销售商品下的商品类型
            Map<String, Object> goodsInfo = CuccOfferOriginalInfoCache.get(offerId);
            List<Map<String, Object>> saleGoods = KiteMapUtils.getValue(goodsInfo, "saleGoods");
            if (!KiteListUtils.isEmpty(saleGoods)) {
                List<String> offerTypes = saleGoods.stream().map(map -> {
                    String goodsSku = KiteMapUtils.getString(map, "goodsSku");
                    Offer offer = OfferCache.get(goodsSku);
                    if(null !=offer) {
                        return offer.getOfferType();
                    }else {
                        return "0";
                    }
                }).collect(Collectors.toList());
                offerType = Collections.max(offerTypes);
/*                if(!saleGoods.stream().anyMatch(sale->KiteStringUtils.equals(KiteMapUtils.getString(sale,"status"),"LAUNCHED")
                    && KiteStringUtils.equals(KiteMapUtils.getString(sale,"goodsSku"),singleGoodsSku))){
                    ErrorConsts.BUSI_COMMON_ERROR.throwOut("商品不存在或已下架！");
                }*/
            }
            else {
                offerType = OfferCache.get(offerId).getOfferType();
            }

            // 新配置，如果旧配置信息取不到则取新配置
            String taskCode = this.querySceneInstService.getExtParameterValue(KiteWebContext.getContext().getCurrentSceneInstId(), "taskCode");
            String tacheCode = this.querySceneInstService.getExtParameterValue(KiteWebContext.getContext().getCurrentSceneInstId(), "nodeCode");
            // 为空则认为是录入
            if (KiteStringUtils.isEmpty(tacheCode)) {
                tacheCode = "OrderInput";
            }
            // 服务提供
            String serviceOfferIdd = this.querySceneInstService.getExtParameterValue(KiteWebContext.getContext().getCurrentSceneInstId(), "serviceOfferId");
            // 为空则认为是录入
            if (!KiteStringUtils.isEmpty(serviceOfferIdd)) {
                serviceOfferId = serviceOfferIdd;
            }

            Offer offer = OfferCache.get(offerId);
            if (Objects.nonNull(offer) && KiteStringUtils.isEmpty(offerType)) {
                offerType = offer.getOfferType();
            }
            String objId = offer.getCateId();

            List<OfferAttr> offerAttrs = OfferAttrCache.get(offerId);
            if (KiteStringUtils.isEmpty(objId) && !KiteListUtils.isEmpty(offerAttrs)) {
                OfferAttr catIdAttr = offerAttrs.stream().filter(attr -> "cateId".equals(attr.getFieldName())).findAny()
                    .orElse(new OfferAttr());
                objId = catIdAttr.getDefaultValue();
            }
            // 1、先根据任务编码获取（环节编码不满足一个环节多个任务的模板配置要求） 先优先取Offer_id下的配置
            PageNavigationVO pageNavigationVO = this.getPageNavigationVOByOfferId(oldServiceOfferId, taskCode, offerType, offerId).getResultObject();

            // 2、为空再取分类下的配置
            if (KiteObjectUtils.isEmpty(pageNavigationVO)) {
                pageNavigationVO = this.getPageNavigationVO(oldServiceOfferId, taskCode, offerType, objId).getResultObject();
            }
            // 2、根据tacheCode 查询
            if (KiteObjectUtils.isEmpty(pageNavigationVO)) {
                pageNavigationVO = this.getPageNavigationVOByOfferId(oldServiceOfferId, tacheCode, offerType, offerId).getResultObject();
            }

            if (KiteObjectUtils.isEmpty(pageNavigationVO)) {
                pageNavigationVO = this.getPageNavigationVO(oldServiceOfferId, tacheCode, offerType, objId).getResultObject();
            }

            // 收入归集导入特殊处理处理
            if(!KiteStringUtils.isEmpty(sceneInstId)){
                String sceneActionType = this.querySceneInstService.getExtParameterValue(sceneInstId, "sceneActionType");
                if(!KiteStringUtils.isEmpty(sceneActionType)){
                    PageNavigationVO groupPageNavigation = this.getPageNavigationVOByOfferId(oldServiceOfferId, sceneActionType, offerType, offerId).getResultObject();
                    // 2、为空再取分类下的配置
                    if (KiteObjectUtils.isEmpty(groupPageNavigation)) {
                        groupPageNavigation = this.getPageNavigationVO(oldServiceOfferId, sceneActionType, offerType, objId).getResultObject();
                    }
                    if(!KiteObjectUtils.isEmpty(groupPageNavigation)){
                        return ErrorConsts.SUCCESS.getResult(groupPageNavigation);
                    }
                }
            }
            return ErrorConsts.SUCCESS.getResult(pageNavigationVO);
        }
        // 兼容旧配置
        if (StringUtils.isNotBlank(offerId)) {
            PageNavigationVO result = pageNavigationService.getPageNavigationByOffer(offerId, oldServiceOfferId);
            if (result != null) {
                return ErrorConsts.SUCCESS.getResult(result);
            }
        }

        return ErrorConsts.SUCCESS.getResult(KitePageNavigationCache.get(oldServiceOfferId, offerType));
    }

    @KiteTransactional
    @ApiOperation(value = "商机内容回显", notes = "商机内容回显")
    @ApiImplicitParams({@ApiImplicitParam(name = "offerId", value = "销售品标识",required = true),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true),
        @ApiImplicitParam(name = "oppoNum", value = "商机编码", required = true)
    })
    @GetMapping("/oppoProdInfo")
    public DataResult initOppoInfoToScene(@RequestParam(required = true) String offerId,
                                                       @RequestParam String sceneInstId, @RequestParam(required = true) String oppoNum) {
        operateSceneInstService.putExtParameter(sceneInstId,"oppo_init","T");
        String custId = KiteWebContext.getContext().getCustId();
        KiteSceneInst sceneInst = this.querySceneInstService
            .getSceneInst(sceneInstId, custId);
        String goodsSpu = offerId;
        if (InstType.PROD_INST.equals(sceneInst.getRootInstType())) {
            //基础销售品
            offerId = ProductCache.get(getSpecId(sceneInst)).getBaseOfferId();
        }
        else {
            offerId = getSpecId(sceneInst);
        }
        Map<String,Object> oppoDetail = OppoToSceneUtils.getInst().putOppoToContext(oppoNum,sceneInstId);
        OppoToSceneUtils.getInst().initOppoProdToScene(oppoDetail,sceneInstId,offerId,custId,goodsSpu);
        operateSceneInstService.removeExtParameter(sceneInstId,"oppo_init");
        return ErrorConsts.SUCCESS.getResult("SUCCESS");
    }

    private DataResult<PageNavigationVO> getPageNavigationVO(String serviceOfferId, String tacheCode, String offerType, String objId) {


        // 1、根据商品ID来获取，获取不到，则先根据商品分类来获取，优先取分类下的配置
        // 根据商品ID来获取，优先取商品下的配置 obj_id 可以是分类ID，也可以是offer_id

        PageNavigationVO pageNavigationVO = CuccKitePageNavigationCache
            .get(serviceOfferId, tacheCode, offerType, objId);

        // 2，不存在，则获取，service_offer_id为-1的数据，即表示相同商品，不同业务，不同环节都用同一个模版
        if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO = CuccKitePageNavigationCache.get("-1", tacheCode, offerType, objId);
        }
        // 3、不存在，则获取obj_id为空的数据，即表示所有商品同一业务，不同环节都用同一个模版
        if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO = CuccKitePageNavigationCache.get(serviceOfferId, tacheCode, offerType, null);
        }
        // 4，不存在，则获取，service_offer_id为-1，obj_id为空的数据的数据，即表示所有商品不同业务，不同环节，不同商品都用同一个模版
        if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO = CuccKitePageNavigationCache.get("-1", tacheCode, offerType, null);
        }

        if (Objects.nonNull(pageNavigationVO) && KiteStringUtils.isNotEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO.setPageType(DcPublicCache.getCodea("20201202001", tacheCode));
            return ErrorConsts.SUCCESS.getResult(pageNavigationVO);
        }
        return ErrorConsts.SUCCESS.getResult(null);
    }

    private DataResult<PageNavigationVO> getPageNavigationVOByOfferId(String serviceOfferId, String tacheCode, String offerType, String offerId) {


        // 1、根据商品ID来获取，获取不到，则先根据商品分类来获取，优先取分类下的配置
        // 根据商品ID来获取，优先取商品下的配置 obj_id 为offer_id

        PageNavigationVO pageNavigationVO = CuccKitePageNavigationCache
            .get(serviceOfferId, tacheCode, offerType, offerId);

        // 2，不存在，则获取，service_offer_id为-1的数据，即表示相同商品，不同业务，不同环节都用同一个模版
        if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO = CuccKitePageNavigationCache.get("-1", tacheCode, offerType, offerId);
        }

        if (Objects.nonNull(pageNavigationVO) && KiteStringUtils.isNotEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO.setPageType(DcPublicCache.getCodea("20201202001", tacheCode));
            return ErrorConsts.SUCCESS.getResult(pageNavigationVO);
        }
        return ErrorConsts.SUCCESS.getResult(null);
    }

    @ApiOperation(value = "生成套餐修改场景对象", notes = "生成套餐修改场景对象")
    @ApiImplicitParams({@ApiImplicitParam(name = "serviceOfferId", value = "服务提供标识", required = true),
        @ApiImplicitParam(name = "templateId", value = "场景模板标识", required = true),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true),
        @ApiImplicitParam(name = "offerId", value = "销售品标识")
    })
    @GetMapping("/modOffer")
    public DataResult<SceneVO> createModOfferScene(@RequestParam String serviceOfferId, @RequestParam String templateId,
                                                   @RequestParam(required = false) String offerId, @RequestParam String sceneInstId) {
        DataResult<SceneVO> result = new DataResult<SceneVO>();
        if (StringUtil.isBlank(offerId)) {
            offerId = getSpecId(getSceneInst(sceneInstId));
        }
        AcceptRequestInDTO acceptRequest = new AcceptRequestInDTO();
        acceptRequest.setSceneInstId(sceneInstId).setSceneTemplateId(templateId).setOfferId(offerId)
            .setServiceOfferId(serviceOfferId);
        operateSceneInstService.putExtParameter(sceneInstId, "changeServiceOfferId", serviceOfferId);
        result = sceneService.callEngine(acceptRequest);
        operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.BUSI_CHANGE, "T");
        return result;
    }

    @ApiOperation(value = "获取场景实例基本信息(如果场景实例缓存不存在，则从购物车和过程实例表还原场景实例)", notes = "获取场景实例基本信息(如果场景实例缓存不存在，则从购物车和过程实例表还原场景实例)")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例id", required = true),
        @ApiImplicitParam(name = "custId", value = "客户id", required = true)
    })
    @GetMapping("/sceneInst")
    public DataResult<KiteSceneInst> getSceneInst(String sceneInstId, String custId) {
        return ErrorConsts.SUCCESS.getResult(querySceneService.getSceneInst(sceneInstId, custId));
    }

    /**
     * 获取场景实例
     *
     * @param sceneInstId 场景实例标识
     * @return
     */
    private KiteSceneInst getSceneInst(String sceneInstId) {
        return querySceneService.getSceneInst(sceneInstId, KiteWebContext.getContext().getCustId());
    }

    /**
     * 获取规格标识
     *
     * @return
     */
    private String getSpecId(KiteSceneInst kiteSceneInst) {
        KiteOfferInst offerInst = querySceneInstService
            .getOfferInst(kiteSceneInst.getCustId(), kiteSceneInst.getRootInstId());

        if (Objects.nonNull(offerInst)) {
            return offerInst.getSpecId();
        }
        else {
            return "";
        }

    }

    @ApiOperation(value = "获取新场景对象", notes = "获取新场景对象")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true)
    })
    @GetMapping("/newScene")
    public DataResult<SceneVO> refreshScene(@RequestParam String sceneInstId) {
        return ErrorConsts.SUCCESS.getResult(SceneVOCache.get(sceneInstId));
    }

    @ApiOperation(value = "获取进度信息", notes = "获取进度信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true)
    })
    @GetMapping("/progressInfo")
    public DataResult<TrackInfoVO> getProgressInfo(@RequestParam String orderId) {
        return ErrorConsts.SUCCESS.getResult(this.queryFlowService.getOrderProgressInfo(orderId));
    }

    @ApiOperation(value = "获取回执信息", notes = "获取回执信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true)
    })
    @GetMapping("/receiptInfo")
    public DataResult<ReceiptInfoVO> getReceiptInfo(@RequestParam(value = "orderId") String orderId,
                                                    @RequestParam(value = "taskId") String taskId) {
        return ErrorConsts.SUCCESS.getResult(this.queryReceiptService.getReceiptInfo(orderId, taskId));
    }

    @ApiOperation(value = "获取OSS进度信息", notes = "获取OSS进度信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true),
        @ApiImplicitParam(name = "taskCode", value = "任务编码", required = true)
    })
    @GetMapping("/ossProgressInfo")
    public DataResult<OssTrackInfoVO> getOssProgressInfo(@RequestParam String orderId, @RequestParam String taskCode) {
        return ErrorConsts.SUCCESS.getResult(this.queryFlowService.getOssProgressInfo(orderId, taskCode));
    }

    @ApiOperation(value = "获取一站式进度信息", notes = "获取一站式进度信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true),
        @ApiImplicitParam(name = "taskCode", value = "任务编码", required = true),
        @ApiImplicitParam(name = "taskId", value = "任务id", required = true)
    })
    @GetMapping("/oneStopProgressInfo")
    public DataResult<OneStopTrackInfoVO> getOneStopProgressInfo(@RequestParam String orderId,
                                                                 @RequestParam String taskCode, @RequestParam String taskId) {
        return ErrorConsts.SUCCESS.getResult(this.queryFlowService.getOneStopProgressInfo(orderId, taskCode, taskId));
    }

    @KiteTransactional
    @ApiOperation(value = "更新购物车状态", notes = "预览时，返回上一步信息录入页面，需要更新购物车状态")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例Id", required = true)
    })
    @PostMapping("/updateCartStatus")
    public DataResult<Boolean> updateCartStatus(@RequestParam String sceneInstId) {
        KiteSceneInst kiteSceneInst = this.querySceneInstService.getSceneInst(sceneInstId);
        String askSource = kiteSceneInst.getAskSource();
        String cartId = kiteSceneInst.getCartId();
        if (KiteStringUtils.isEmpty(cartId)) {
            Long staffId = ContextUtil.getUserId();
            // 获取购物车的分片键，调用ES进行查询，暂时先放在登录信息缓存中,方便场景加载的时候从购物车中获取数据需要通过分片键获取 ，后续改动
            IQueryKiteShoppingCartService queryKiteShoppingCartService = SpringUtil
                .getBean(IQueryKiteShoppingCartService.class);
            // 获取分片键 cartId
            Long cartIdd = queryKiteShoppingCartService.getShoppingCartIdByEs(staffId.toString()).getResultObject();
            if (!KiteObjectUtils.isEmpty(cartIdd)) {
                cartId = cartIdd.toString();
            }
        }
        if (!KiteStringUtils.equals(LocalKeyConsts.ASK_SOURCE_ORDER, askSource)) {
            KiteCartStatusModifyEvent kiteCartStatusModifyEvent = new KiteCartStatusModifyEvent(this,
                KiteWebContext.getContext().getCustId(),
                ContextUtil.getUserId().toString(),
                ContextUtil.getLoginInfo().getUserInfo().getUserName(),
                cartId, KeyConsts.SHOPPING_CART_GROUP_STATUS_INPUT, Collections.singletonList(sceneInstId));
            applicationContext.publishEvent(kiteCartStatusModifyEvent);
        }
        return ErrorConsts.SUCCESS.getResult(Boolean.TRUE);
    }

    /**
     * 把当前场景添加到购物车，购物车分组状态是：待录入
     *
     * @param sceneInstId
     */
    private void cacheShoppingCartGroup(String sceneInstId, String cartId) {
        com.iwhalecloud.bss.kite.cucc.web.service.ISceneService cuccSceneService = SpringUtil.getBean(com.iwhalecloud.bss.kite.cucc.web.service.ISceneService.class);
        cuccSceneService.cacheShoppingCartGroup(sceneInstId, cartId);

        /*final String userId = ContextUtil.getUserId().toString();
        final String custId = KiteWebContext.getContext().getCustId();
        final String sessionId = ContextUtil.getHttpSessoinId();
        final String transactionId = KiteTransactionUtils.getTransactionId();
        SimpleLoginInfo simpleLoginInfo = ContextUtil.getSimpleLoginInfo();
        if (KiteStringUtils.isEmpty(cartId)) {
            cartId = queryShoppingCartService.getShoppingCartId(userId, custId);
            KiteSceneInst kiteSceneInst = querySceneInstService.getSceneInst(sceneInstId);
            kiteSceneInst.setCartId(cartId);
            operateSceneInstService.setSceneInst(kiteSceneInst);
        }
        String _cart = cartId;
        CompletableFuture.runAsync(() -> {
            try {
                KiteTransactionUtils.beginTransaction();
                ContextUtil.setHttpSessoinId(sessionId);
                // 兼容接口调用
                ContextUtil.putSimpleLoginInfo2ThreadLocal(simpleLoginInfo);
                operateShoppingCartService
                    .cacheShoppingCartGroup(ContextUtil.getSimpleLoginInfo(), sceneInstId, userId, custId,
                        KeyConsts.SHOPPING_CART_GROUP_STATUS_INPUT, _cart);
            } catch (Exception e) {
                e.printStackTrace();
                // just log
                //  logger.error(ErrorConsts.SYSTEM_ERROR.getErrorCode(), e, ErrorConsts.SYSTEM_ERROR.getMsg());
            } finally {
                KiteTransactionUtils.commit();
                KiteTransactionUtils.remove();
                ContextUtil.removeThreadLocal();
            }

        });*/
    }


    /**
     * 初始化客戶信息
     * @param customer
     */
    private void initContext(CuccCustInfoDetailDTO cuccCustInfoDTO) {
        CuccContextCustDTO contextCust = new CuccContextCustDTO();
        if (Objects.nonNull(cuccCustInfoDTO)) {
            KiteBeanUtils.copyProperties(cuccCustInfoDTO, contextCust);
            contextCust.setProvinceCode(cuccCustInfoDTO.getProvinceCode());
            contextCust.setCustName(cuccCustInfoDTO.getCustName());
            contextCust.setLanId(cuccCustInfoDTO.getCityCode());
            contextCust.setRegionId(cuccCustInfoDTO.getBcityCode());
            contextCust.setCustType(cuccCustInfoDTO.getCustClassType());
            contextCust.setBbssCustId(cuccCustInfoDTO.getBbssCustId());
            contextCust.setCbssId(cuccCustInfoDTO.getCustId());
            contextCust.setAttrs(cuccCustInfoDTO.getAttrs());
            //商机
            contextCust.setOppoNum(cuccCustInfoDTO.getOppoNum());
            contextCust.setOppoName(cuccCustInfoDTO.getOppoName());
        }
        KiteWebContext.initContext(KiteWebContext.getKiteContextId(), contextCust);
        CuccContextCustCache.put(ContextUtil.getLoginInfo().getUserInfo().getUserCode(), cuccCustInfoDTO.getCustId(), contextCust);
    }
}
